#lang racket

(require racket/match)

(require "utilities.scm")
(require "box.scm")
(require "parser.scm")
(require "syntax-object.scm")
(require "resolve.scm")
(require "environment.scm")
(require "interpret.scm")
(require "scope-sets.scm")

;;; scheme builtins
;;

(define-syntax define-builtins
  (syntax-rules ()
    ((define-builtins builtins <name> ...)
     (define builtins
       `((<name> . ,(box <name>)) ...)))))

(define-builtins builtins
  cons car cdr list null?
  box box-value set-box-value!
  = eq? equal? not
  + - * /
  display newline print
  error

  ;; predicates from R5RS  
  boolean?
  pair?
  symbol?
  number? even? odd?
  char?
  string?
  vector?
  procedure?

  ;; syntax-object manipulation
  syx syx-id?
  syn-car syn-cdr
  identifier-equal?
  )

(define (check file)
  (print (list 'processing file))
  (let* ((prg (parse-file file))
	 (cod (resolve-program prg builtins)))
    (print (list 'code cod))
    (print (list 'raw-code))
    (for-each print (syn->datum cod))))

(define (go file)
  (let* ((prg (parse-file file))
	 (cod (resolve-program prg builtins)))
    ;; TODO:
    ;; listing the specials here is probably incorrect
    ;; if for example a definition of macro redefines that name
    ;; so the list of specials should be communicated to interpret from resolve
    (interpret-program cod (env builtins (list 'lambda 'begin 'if 'quote)))))
